package com.song.Utils;

import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.NamingFactory;
import com.alibaba.nacos.api.naming.NamingService;
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.song.enumeration.RpcError;
import com.song.exception.RpcException;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

import java.net.InetSocketAddress;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

/**
 * 管理Nacos连接等工具类
 */

@Slf4j
@Data
public class NacosUtil {
    private static final NamingService namingService;
    private static final Set<String> serviceNamesSet = new HashSet<>();//存储所有的服务名称
    private static InetSocketAddress address;

    private static final String SERVER_ADDR = "10.1.124.24:8848";//存Nacos在线注册中心的host和port
    static {
        namingService = getNamingService();//连接的过程写在了静态代码块中，在类加载时自动连接
    }

    //静态工厂方法创建实例
    //连接Nacos
    public static NamingService getNamingService() {
        try {
            return NamingFactory.createNamingService(SERVER_ADDR);//通过 NamingFactory 创建 NamingService 连接 Nacos
        } catch (NacosException e) {
            log.error("连接Nacos时发生错误：", e);
            throw new RpcException(RpcError.REGISTER_SERVICE_FAILED);
        }
    }

    //Nacas注册服务，并向服务Set集合添加该服务，为遍历服务 和 注销服务
    public static void registerService(String serviceName, InetSocketAddress address) {
        try {
            //Nacos注册
            namingService.registerInstance(serviceName, address.getHostName(), address.getPort());
            serviceNamesSet.add(serviceName);

            NacosUtil.address = address;
        } catch (NacosException e) {
            log.error("注册服务时发生错误：",e);
            throw new RpcException(RpcError.REGISTER_SERVICE_FAILED);
        }
    }

    public static void clearRegistry() {
        if(!serviceNamesSet.isEmpty() && address != null) {
            String host = address.getHostName();
            int port = address.getPort();

            Iterator<String> iter = serviceNamesSet.iterator();

            while(iter.hasNext()) {
                String serviceName = iter.next();

                try {
                    namingService.deregisterInstance(serviceName, host, port);//NamingService类 将此服务进行注销
                } catch (NacosException e) {
                    log.error("注销服务 {} 失败", serviceName, e);
                }
            }
            log.info("已注销所有服务");
        }
    }

    public static List<Instance> getAllInstance(String serviceName) throws NacosException {
        List<Instance> allInstances = namingService.getAllInstances(serviceName);
        return allInstances;
    }

//    public static Instance getInstance(String serviceName) throws NacosException {
//        return namingService.selectOneHealthyInstance(serviceName);
//    }
}
